from django.core.cache import cache
from django.db import connection

from django.utils.deprecation import MiddlewareMixin
from django.middleware.csrf import get_token
from django.http.response import HttpResponseNotFound
import time

MAX_REQUEST_PER_SECOND = 10  # 每秒访问次数


# https://blog.csdn.net/weixin_43582101/article/details/88318141

class MyMiddleware(MiddlewareMixin):
    def process_request(self, request):
        get_token(request)


# 防爬
class RequestBlockingMiddleware(MiddlewareMixin):
    """
    一秒内访问次数不能超过2次
    """

    def process_request(self, request):
        now = time.time()
        request_queue = request.session.get('request_queue', [])
        if len(request_queue) < MAX_REQUEST_PER_SECOND:
            request_queue.append(now)
            request.session['request_queue'] = request_queue
        else:
            time0 = request_queue[0]

            if (now - time0) < 1:
                time.sleep(5)
                request_queue.append(time.time())
                request.session['request_queue'] = request_queue[1:]


# 防爬
class SimpleMiddleware(MiddlewareMixin):
    """
    爬虫拦截器
    在headers里的agent检测
    """

    def process_request(self, request):
        http_user_agent = request.META.get('HTTP_USER_AGENT')
        # remote_addr = request.META.get('REMOTE_ADDR')
        http_user_agent = str(http_user_agent).lower()

        if "py" in http_user_agent or "ssl" in http_user_agent:
            return HttpResponseNotFound(
                content="<h1>Not Found</h1><p>The requested URL was not found on this server.</p>"
            )
        return None

    def process_response(self, request, response):
        return response


# 统计在线数量的中间件
class CountOnlineMiddlewareMixin(MiddlewareMixin):

    def process_request(self, request):
        # 获取当前session key
        session_key = request.session.session_key
        # 获取当前访问用户的IP
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = request.META['REMOTE_ADDR']

        # 判断用户是否登录
        if request.session.get('user_info', False):
            # 因为已经在session中配置了自动更新时间了，下面操作不需要
            # # 在线的话每当用户访问页面要更新session 时间，防止session失效
            # request.session.set_expiry(SESSION_COOKIE_AGE)
            # 统计在线用户，先生成唯一key
            online_key = 'count_online_id_{_id}_session_{_session}'.format(
                _id=request.session.get('user_info')['uid'], _session=session_key)
            # 设置过期时间，或者重新设置过期时间
            cache.set(online_key, 'online')

        # 把统计数放入请求中，方便在模板中使用
        # 通过通配符获取 count_online 的key 有多少个
        # 如果用户不再看网页，session 和 cache 的key 会自动过期，自动删除
        request.online_member_count = len(cache.keys("count_online_id_*"))
        request.current_visitor_ip = ip

    # 用来查看sql语句的debug 关闭
    # def process_response(self, request, response):
    #     for query in connection.queries:
    #         nice_sql = query['sql'].replace('"', '').replace(',', ', ')
    #         sql = "\033[1;31m[%s]\033[0m %s" % (query['time'], nice_sql)
    #         print(sql)
    #
    #     return response


'''
lxcsdn = [
    "https://blog.csdn.net/weixin_43582101/column/info/33034",
    "https://blog.csdn.net/weixin_43582101/article/details/86563910",
    "https://blog.csdn.net/weixin_43582101/article/details/86567367",
]

# 设置请求头和访问间隔
ips = [None]      # 存储客户端最后一次访问的ip地址   空列表也是列表，None类型只有None一个值
# ips=[None] 为了防止 list index out of range。
last = 0           # 存储客服端最后一次访问时间

def isCraw(func):
    def wrapper(*args,**kwargs):
        global ips,last       #声明全局变量
               #request.META 是一个字典,包含了所有本次HTTP请求的Header信息
        agent = args[0].META.get('HTTP_USER_AGENT') #获取请求头部信息
        if 'Mozilla' not in agent and 'Safari' not in agent and 'Chrome'not in agent:
            return HttpResponse(random.choice(lxcsdn))
        else:
            ip = args[0].META.get('REMOTE_ADDR') #客户端IP地址
# 什么是remote_addr:
# remote_addr 是服务端根据请求TCP包的ip指定的。假设从client到server中间没有任何代理，
# 那么web服务器（Nginx，Apache等）就会把client的IP设为IPremote_addr；
# 如果存在代理转发HTTP请求，web服务器会把最后一次代理服务器的IP设置为remote_addr
            now = time.time()
            if ip==ips[0] and now-last<2:            #为了防止误伤
                return HttpResponse("Are you curious about what happened? If you read this sentence carefully, you will know what happened. so the page is not found , But is you didn't find it ! " )
            last = now
            ips.pop()
            ips.append(ip)
            return func(*args,**kwargs)
    return wrapper
'''
